﻿using Lg.Core;
using Lg.Core.Exceptions;
using Lg.Core.Extensions;
using Lg.Core.Validate;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory;
using NPOI.POIFS.FileSystem;
using Snowflake.Core;
using Survey.Core;
using Survey.Models;
using Survey.Models.Dto;
using Survey.Models.Where;
using System.Data;

namespace Survey.Web.Controllers
{
    [Route("api/sys/[action]")]
    [ApiController]
    public class SysApiController(IDbContextFactory<SurveyDbContext> dbContextFactory,IMemoryCache cache, IdWorker idWorker) : Controller
    {
        readonly IMemoryCache _cache = cache;
        readonly IdWorker _idWorker = idWorker;
        readonly IDbContextFactory<SurveyDbContext> _dbContextFactory = dbContextFactory;
        readonly RtMsg _rtmsg= new() { code=100,msg="未知错误"};
        /// <summary>
        /// 登陆
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<RtMsg> Login(LoginModel model)
        {
            return await Task.Run(() =>
            {
                using var dbContext=_dbContextFactory.CreateDbContext();
                var dbModel= dbContext.Admin.FirstOrDefault(x=>x.Account==model.Account&&x.IsDelete==0&&x.LockState==0);
                if(dbModel!=null&&dbModel.Password==Lg.Core.Encryption.MD5.Encrypt(model.Password!))
                {
                    HttpContext.Session.SetString("LoginAdmin", dbModel.ToJsonString());
                    _rtmsg.code = 0;
                    _rtmsg.msg = "success";
                }
                else
                {
                    _rtmsg.msg = "帐号或密码有误";
                }
                return _rtmsg;
            });
        }
        [HttpGet]
        public async Task<RtMsg> GetTemplates([FromQuery]TemplateWhere where)
        {
            return await Task.Run(() =>
            {
                using var dbContext=_dbContextFactory.CreateDbContext();
                var query= where.Process(dbContext.Template.Where(x=>x.IsDelete==0),out int count);
                _rtmsg.code = 0;
                _rtmsg.msg = "Success";
                _rtmsg.data = query.ToList();
                _rtmsg.count=count;
                return _rtmsg;
            });
        }
        [HttpPost]
        public async Task<RtMsg> EditTemplate(TemplateEditModel model)
        {
            return await Task.Run(() =>
            {
                using var dbContext = _dbContextFactory.CreateDbContext();
                var dbModel= dbContext.Template.FirstOrDefault(x=>x.Id==model.Id);
                if (dbModel != null)
                {
                    dbModel.CopyData(model);
                    if (dbContext.Entry(dbModel).State == EntityState.Modified)
                    {
                       int i= dbContext.SaveChanges();
                        if (i > 0)
                        {
                            _rtmsg.code = 0;
                            _rtmsg.msg = "Success";
                        }

                    }
                    else
                    {
                        _rtmsg.msg = "没有任何改动！";
                    }
                }
                else
                {
                    _rtmsg.msg = "目标不存在！";
                }
                return _rtmsg;
            });
        }

        [HttpPost]
        public async Task<RtMsg> AddTemplate(Template model)
        {
            return await Task.Run(() =>
            {
                model.Id = _idWorker.NextId();
                model.IsDelete = 0;
                using var dbContext = _dbContextFactory.CreateDbContext();
                dbContext.Template.Add(model);
                int i = dbContext.SaveChanges();
                if (i > 0)
                {
                    _rtmsg.code = 0;
                    _rtmsg.msg = "Success";
                }
                return _rtmsg;
            });
        }
        [HttpPost]
        public async Task<RtMsg> DeleteTemplate(IdentityModel model)
        {
            return await Task.Run(() =>
            {
                using var dbContext = _dbContextFactory.CreateDbContext();
                var dbModel = dbContext.Template.FirstOrDefault(x => x.Id == model.Id && x.IsDelete == 0);
                if (dbModel != null)
                {
                    dbModel.IsDelete = 1;
                    int i = dbContext.SaveChanges();
                    if (i > 0)
                    {
                        _rtmsg.code = 0;
                        _rtmsg.msg = "Success";
                    }
                }
                else
                {
                    _rtmsg.msg = "目标不存在！";
                }
                return _rtmsg;
            });
        }
        [HttpGet]
        public async Task<RtMsg> GetAdmins([FromQuery] AdminWhereModel where)
        {
            return await Task.Run(() =>
            {
                using var dbContext = _dbContextFactory.CreateDbContext();
                var query = where.Process(dbContext.Admin.Where(x => x.IsDelete == 0), out int count);
                _rtmsg.code = 0;
                _rtmsg.msg = "Success";
                _rtmsg.data = query.ToList();
                _rtmsg.count = count;
                return _rtmsg;
            });
        }
        [HttpPost]
        public async Task<RtMsg> AddAdmin(Admin model)
        {
            return await Task.Run(() =>
            {
                model.Account.Requird();
                model.Password.Requird();
                model.Password = Lg.Core.Encryption.MD5.Encrypt(model.Password);
                model.Id = _idWorker.NextId();
                model.IsDelete = 0;
                using var dbContext = _dbContextFactory.CreateDbContext();
                dbContext.Admin.Add(model);
                int i = dbContext.SaveChanges();
                if (i > 0)
                {
                    _rtmsg.code = 0;
                    _rtmsg.msg = "Success";
                }
                return _rtmsg;
            });
        }

        [HttpPost]
        public async Task<RtMsg> EditAdmin(AdminEditModel model)
        {
            return await Task.Run(() =>
            {
                model.Id.Requird();
                if (!string.IsNullOrEmpty(model.Password) && model.Password.Trim().Length > 0)
                {
                    model.Password = Lg.Core.Encryption.MD5.Encrypt(model.Password);
                }
                using var dbContext = _dbContextFactory.CreateDbContext();
                var dbModel = dbContext.Admin.FirstOrDefault(x => x.Id == model.Id);
                if (dbModel != null)
                {
                    dbModel.CopyData(model);
                    if (dbContext.Entry(dbModel).State == EntityState.Modified)
                    {
                        int i = dbContext.SaveChanges();
                        if (i > 0)
                        {
                            _rtmsg.code = 0;
                            _rtmsg.msg = "Success";
                        }

                    }
                    else
                    {
                        _rtmsg.msg = "没有任何改动！";
                    }
                }
                else
                {
                    _rtmsg.msg = "目标不存在！";
                }
                return _rtmsg;
            });
        }
        [HttpPost]
        public async Task<RtMsg> DeleteAdmin(IdentityModel model)
        {
            return await Task.Run(() =>
            {
                using var dbContext = _dbContextFactory.CreateDbContext();
                var dbModel = dbContext.Admin.FirstOrDefault(x => x.Id == model.Id&&x.IsDelete==0);
                if (dbModel != null)
                {
                    dbModel.IsDelete = 1;
                    int i = dbContext.SaveChanges();
                    if (i > 0)
                    {
                        _rtmsg.code = 0;
                        _rtmsg.msg = "Success";
                    }
                }
                else
                {
                    _rtmsg.msg = "目标不存在！";
                }
                return _rtmsg;
            });
        }

        [HttpGet]
        public async Task<RtMsg> GetCourseEvaluate([FromQuery] CourseEvaluateWhere where)
        {
            return await Task.Run(() =>
            {
                using var dbContext = _dbContextFactory.CreateDbContext();
                var query = where.Process(dbContext.CourseEvaluate.OrderByDescending(x=>x.Id), out int count);
                _rtmsg.code = 0;
                _rtmsg.msg = "Success";
                _rtmsg.data = query.ToList();
                _rtmsg.count = count;
                return _rtmsg;
            });
        }
        [HttpPost]
        public async Task<RtMsg> AddCourseEvaluate(CourseEvaluate model)
        {
            return await Task.Run(() =>
            {
                model.Id = _idWorker.NextId();
                using var dbContext = _dbContextFactory.CreateDbContext();
                dbContext.CourseEvaluate.Add(model);
                int i = dbContext.SaveChanges();
                if (i > 0)
                {
                    _rtmsg.code = 0;
                    _rtmsg.msg = "Success";
                }
                return _rtmsg;
            });
        }

        [HttpPost]
        public async Task<RtMsg> EditCourseEvaluate(CourseEvaluateEditModel model)
        {
            return await Task.Run(() =>
            {
                using var dbContext = _dbContextFactory.CreateDbContext();
                var dbModel = dbContext.CourseEvaluate.FirstOrDefault(x => x.Id == model.Id);
                if (dbModel != null)
                {
                    dbModel.CopyData(model);
                    if (dbContext.Entry(dbModel).State == EntityState.Modified)
                    {
                        int i = dbContext.SaveChanges();
                        if (i > 0)
                        {
                            _rtmsg.code = 0;
                            _rtmsg.msg = "Success";
                        }

                    }
                    else
                    {
                        _rtmsg.msg = "没有任何改动！";
                    }
                }
                else
                {
                    _rtmsg.msg = "目标不存在！";
                }
                return _rtmsg;
            });
        }
        [HttpPost]
        public async Task<RtMsg> DeleteCourseEvaluate(IdentityModel model)
        {
            return await Task.Run(() =>
            {
                using var dbContext = _dbContextFactory.CreateDbContext();
                var dbModel = dbContext.CourseEvaluate.FirstOrDefault(x => x.Id == model.Id);
                if (dbModel != null)
                {
                    dbContext.Remove(dbModel);
                    int i = dbContext.SaveChanges();
                    if (i > 0)
                    {
                        _rtmsg.code = 0;
                        _rtmsg.msg = "Success";
                    }
                }
                else
                {
                    _rtmsg.msg = "目标不存在！";
                }
                return _rtmsg;
            });
        }
        /// <summary>
        /// 清空当前CourseEvaluate表的所有数据
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<RtMsg> ClearCourseEvaluate()
        {
            return await Task.Run(() =>
            {
                using var dbContext=_dbContextFactory.CreateDbContext();
                var list=  dbContext.CourseEvaluate.ToList();
                if(list.Count > 0)
                {
                    int i = dbContext.Database.ExecuteSqlRaw("TRUNCATE TABLE [CourseEvaluate]");
                    if (i > 0)
                    {
                        _rtmsg.code = 0;
                        _rtmsg.msg = "sucess";
                    }
                    Task.Run(() =>
                    {
                        var excel = new Lg.Core.FileHelper.Excel().AddSheet(list, null, $"{DateTime.Now.ToString("yyyy-MM-dd")}");
                        excel.Save();
                    });
                }
                else
                {
                    _rtmsg.msg="无数据可清除";
                }               
                return _rtmsg;
            });
        }
        [HttpPost]
        public async Task<RtMsg> ImportCourseEvaluate(IFormFile file)
        {
            return await Task.Run(() =>
            {
               var excel= new Lg.Core.FileHelper.Excel(file);
               var table= excel.ToTable();
                if (table != null && table.Rows.Count > 0)
                {
                    var list= table.ToList<CourseEvaluate>();
                    foreach(var item in list??throw new LgException("数据转换失败,请检查数据列是否正确"))
                    {
                        item.Id = _idWorker.NextId();
                    }
                    using var dbContext=_dbContextFactory.CreateDbContext();
                    dbContext.CourseEvaluate.AddRange(list??throw new LgException("数据解析失败"));
                    int i=dbContext.SaveChanges();
                    _rtmsg.code=0;
                    _rtmsg.msg = $"导入执行完毕，成功/总数：{i}/{list.Count}";
                }
                else
                {
                    _rtmsg.msg="文件不包含数据或数据格式不合法!";
                }
                
                return _rtmsg;
            });
        }

        [HttpPost]
        public async Task<IActionResult> ExportCourseEvaluate(CourseEvaluateWhere where)
        {
            return await Task.Run(() =>
            {
                try
                {
                    where.Page = null;
                    where.Limit = null;
                    using var dbContext = _dbContextFactory.CreateDbContext();
                    var query = where.Process(dbContext.CourseEvaluate, out int count);
                    var list = query.ToList();
                    var excel = new Lg.Core.FileHelper.Excel();
                    byte[] bytes = excel.AddSheet(list, null).GetBytes();
                    return File(bytes, Lg.Core.FileHelper.MimeMaping.GetContentType("xlsx"));
                }catch(Exception ex)
                {
                    throw new LgException(ex.Message);
                }
                
            });
        }

        [HttpGet]
        public async Task<RtMsg> GetGrades()
        {
            return await Task.Run(() =>
            {
                using var dbContext=_dbContextFactory.CreateDbContext();
                var grades=  dbContext.CourseEvaluate.GroupBy(x => x.Grade).Select(g=>new {Grade=g.Key}).ToList();
                _rtmsg.code=0;
                _rtmsg.data = grades;
                _rtmsg.msg = "success";
                _rtmsg.count=grades.Count;
                return _rtmsg;
            });
        }
        [HttpGet]
        public async Task<RtMsg> GetClass(string grade)
        {
            return await Task.Run(() =>
            {
                using var dbContext = _dbContextFactory.CreateDbContext();
                var data = dbContext.CourseEvaluate.Where(x => x.Grade == grade&&x.Class!=null&&x.Class!="").GroupBy(x => x.Class).Select(x => new { Class = x.Key }).ToList();
                _rtmsg.code = 0;
                _rtmsg.msg = "success";
                _rtmsg.data = data;
                _rtmsg.count = data.Count;
                return _rtmsg;
            });
        }

        [HttpGet]
        public async Task<RtMsg> GetCourse([FromQuery] GradeWhere where)
        {
            return await Task.Run(() =>
            {
                using var dbContext = _dbContextFactory.CreateDbContext();
                var data = where.Process(dbContext.CourseEvaluate, out int count).GroupBy(x => x.CourseName).Select(x => new { Course = x.Key }).ToList();
                _rtmsg.code = 0;
                _rtmsg.msg = "success";
                _rtmsg.data = data;
                _rtmsg.count = data.Count;
                return _rtmsg;
            });
        }

        [HttpGet]
        public async Task<RtMsg> GetStudent([FromQuery]GradeWhere where)
        {
            return await Task.Run(() =>
            {
                using var dbContext = _dbContextFactory.CreateDbContext();
                var data = where.Process(dbContext.CourseEvaluate,out int count).GroupBy(x => x.StudentName).Select(x => new { StudentName = x.Key }).ToList();
                _rtmsg.code = 0;
                _rtmsg.msg = "success";
                _rtmsg.data = data;
                _rtmsg.count = data.Count;
                return _rtmsg;
            });
        }
    }
}
